#pragma once
#include "Includes.h"
#include "HL2Interface.h"
#include "Utilities.h"
#include "BoneVector.h"
#include "VMTWrapper.h"

class Entity
{
public:
	virtual void f0000();
	virtual void f0001();
	virtual void f0002();
	virtual void f0003();
	virtual void f0004();
	virtual IClientRenderable* GetClientRenderable();
	virtual void f0006();
	virtual void* GetBaseEntity();

	inline int* fFlags() { return MakePointerGEN< int >( this, Offsets::m_fFlags ); }
	inline int* iHealth() { return MakePointerGEN< int >( this, Offsets::m_iHealth ); }
	inline SD_Tools::Vector* vecViewOffset() { return MakePointerGEN< SD_Tools::Vector >( this, Offsets::m_vecViewOffset ); }
	inline SD_Tools::Vector* vecVelocity() { return MakePointerGEN< SD_Tools::Vector >( this, Offsets::m_vecVelocity ); }
	inline SD_Tools::Vector* vecOrigin() { return MakePointerGEN< SD_Tools::Vector >( this, Offsets::m_vecOrigin ); }
	inline int* iTeamNum() { return MakePointerGEN< int >( this, Offsets::m_iTeamNum ); }
	inline BYTE* dormant() { return MakePointerGEN< BYTE >( this, 0x14A ); } // TODO: Update
	inline DWORD* Weapon() { return MakePointerGEN< DWORD >( this, Offsets::m_hActiveWeapon ); }
	inline char** positionname() { return MakePointerGEN< char* >( this, 0x11C ); } // TODO: Update
	inline BYTE* lifeState() { return MakePointerGEN< BYTE >( this, Offsets::m_lifeState ); }
	inline BonePtr** boneptr() { return MakePointerGEN< BonePtr* >( this, 0x7C4 ); } // TODO: Update
	inline SD_Tools::Vector* getRecoilVec() { return MakePointerGEN< SD_Tools::Vector > (this, Offsets::m_vecPunchAngle); }
	bool GetBone(int index, SD_Tools::Vector* vIn);
	bool GetMidHead(SD_Tools::Vector* Out);
	SD_Tools::Vector GetEyePosition()
	{
		SD_Tools::Vector m_viewOffset = *(SD_Tools::Vector*)((DWORD)this + Offsets::m_vecViewOffset);
		SD_Tools::Vector m_Eye = SD_Tools::MathHelper::AddVector(*this->vecOrigin(), m_viewOffset);
		return m_Eye;
	}
	int GetIndex()
	{
		void* vNetworkable = (void*)((DWORD)this + 0x8);
		typedef int (__thiscall* GetIndex_t)(void*);
		return VMTWrapper::getfunction<GetIndex_t>(vNetworkable, 9)(vNetworkable);
	}
	ClientClass* GetClientClass()
	{
		void* vNetworkable = (void*)((DWORD)this + 0x8);
		typedef ClientClass* (__thiscall* GetClientClass_t)(void*);
		return VMTWrapper::getfunction<GetClientClass_t>(vNetworkable, 2)(vNetworkable);
	}
	void GetVelocity(SD_Tools::Vector& vel);
	CBaseCombatWeapon* GetBaseCombatWeapon();
};